perm filename WALEYE.SAI[SYS,HE] blob sn#056766 filedate 1973-08-02 generic text, type T, neo UTF8
00100	BEGIN "WALEYE" 
00200	
00300	COMMENT   This is a corner finding program using the Hueckel
00400		edge_operator. It will find lines, corners 
00500		with 2 sides and physical corners with 3 sides;
00600	
00700	
00800	REQUIRE "{ } { }" DELIMITERS;
00900	REQUIRE "PREAMB.SAI[SYS,HE]" SOURCE_FILE;
01000	REQUIRE "HELIB[1,3]" LIBRARY;
01100	REQUIRE "VIDSUB[1,PDQ]" LOAD_MODULE;
01200	REQUIRE "PROLOG.HDR[1,PDQ]" SOURCE_FILE;
01300	REQUIRE "EDGE.HDR[VIS,WAP]" SOURCE_FILE;
01400	REQUIRE "SAITRG[SYS,BGB]" SOURCE_FILE;
01500	
01600	DEFINE DINT="2."; COMMENT THIS IS USED AS RADIUS IN WHICH WE
01700			CONSIDER NEW VERTEX TO BE THE SAME AS ONE
01800			FOUND PREVIOUSLY;
01900	
02000	
02100	DEFINE SINDIR="12", COSDIR="13", SINTHETA="9", COSTHETA="10";
02200	
02300	
02400	SHORT REAL SCAL,XCEN,YCEN;
02500	SHORT INTEGER REQUEST,MESS,EXFLAG,DUMMY,MINI,MAXI,DE,INTS,LINS;
02600	SHORT INTEGER SIZE,SUMPT1,SUMPT2,SUMPT3,TVSIZE,PICSIZE,NCORNERS;
02700	INTEGER XXMIN,XXMAX,CORNERNUMBER;
02800	BOOLEAN EXT_LINE;
02900	SHORT INTEGER ARRAY IHIST[-1:16];
03000	INTEGER ARRAY TVBUF[1:2000];
03100	SAFE INTEGER ARRAY PIC[0:9];
03200	
03300	
03400	EXTERNAL PROCEDURE SUMSUB(INTEGER ARRAY TV; INTEGER OPTR1,OPTR2,OPTR3);
03500	EXTERNAL INTEGER PROCEDURE GIOWD(INTEGER ARRAY BUF);
03600	EXTERNAL INTEGER PROCEDURE GETCOR(INTEGER SIZE);
03700	EXTERNAL PROCEDURE INTPNT;
03800	EXTERNAL INTEGER TVWORD,TVCAM,LSIDE,RSIDE,FLINE,LLINE,LINES;
03900	EXTERNAL INTEGER BITS,LINLEN,IWID,TCLIP,BCLIP;
04000	
04100	comment to run without PREAMB the following declarations should be added here;
04200	comment	BOOLEAN DIS_EYE,DEB_EYE,TYP_EYE;
04300	comment REAL ARRAY DIR_EYE[0:10,1:8];
04400	comment INTEGER ARRAY LOOK_AT[1:8];
04500	
04600	DEFINE ⊃="COMMENT", DPYBUF="BUF", INTEGER_ARRAY="INTEGER ARRAY";
04700	DEFINE CRLF="'15&'12", ACRLF="&'15&'12";  DEFINE YES="INCHWL=""Y""";
04800	DEFINE PRINT(FOO)={OUTSTR("  FOO="&CVG(FOO)ACRLF);};
04900	DEFINE WAIT="IF DEB_EYE THEN BEGIN OUTSTR(""...TYPE Y TO CONTINUE...""ACRLF);
05000	             IF INCHWL=""Y"" THEN; END";
05100	
05200	
05300	
05400	
     

00100		SHORT INTEGER X, Y,DX,DY, NHIGH,NLINES,NVERTEX,NDRES;
00200		SHORT INTEGER X_WIDTH,Y_WIDTH;
00300		SHORT INTEGER EDGE_LIMIT, LT_LIMIT, LINE_LIMIT,VERT_LIMIT;
00400		SHORT INTEGER BUF_LIMIT;
00500		SHORT REAL NDTH,NDC,NDS,NDCHI,NDRADIUS,NDGAP;
00600		SHORT REAL NDANG,NDACC, DELTA_X,DELTA_Y,DXY;
00700	
00800	BOOLEAN CAL_COMP; ⊃ IT TRUE THEN MAKE CALCOMP PLOTS OF SOME DISPLAYS;
00900	BOOLEAN CAL2_COMP; ⊃ IT TRUE THEN MAKE CALCOMP PLOTS OF SOME DISPLAYS.
01000			This is used for SET_FOR_SCAN edge displays;
01100	
01200	PROCEDURE INIT;
01300	BEGIN
01400	X←0;Y←0;DX←2;DY←2;
01500	
01600	
01700	⊃ Line finder variables;
01800	NDTH←0.23; ⊃ THIS SETS HALF THE THETA WINDOW FOR EDGE_POINTS FORMING A LINE;
01900	NDC←30.0; ⊃ THIS SETS HALF THE C WINDOW FOR EDGE_POINTS FORMING A LINE;
02000	NDRES←2; ⊃ THIS SETS SPACING IN THE RESIDUAL HISTOGRAM.
02100		   LARGER NUMBER MADE IT EASIER TO FIND A LINE;
02200	NDS←4.; ⊃ THIS SETS THE MINIMUM GAP LENGTH FOR WHICH 2 EDGE_POINTS
02300		  WILL BE JOINED TO FORM A SOLID LINE;
02400	NDCHI←1.0; ⊃ THIS SETS THE MAXIMUM ALLOWABLE CHI-VALUE
02500		      FOR A SET OF POINTS TO BE CONSIDERED A LINE;
02600	NDRADIUS←6; ⊃ RADIUS OF CIRCLE USED TO EXTEND END OF LINES;
02700	NDGAP←0.5; ⊃ MAXIMUM PERCENTAGE OF LENGTH FOR GAP BETWEEN EDGE POINTS;
02800	NDANG←0.15; ⊃ THIS DETERMINES THE ACCEPTABLE DIFFERENCE IN 
02900		     FOR TWO LINES TO BE MADE INTO ONE;
03000	NDACC←.75;  ⊃ THIS SETS THE ACCEPTABLE PERPENDICULAR DISTANCE BETWEEN
03100		   LINES AND VERTEX CENTER FOR A THREE LINE VERTEX;
03200	NHIGH←4; ⊃ IF THE NUMBER OF GOOD EDGE POINTS 
03300		   IS ≥ NHIGH + 1 THEN A LINE WILL BE FOUND EVENUTALLY;
03400	
03500	CAL_COMP←CAL2_COMP←0;
03600	
03700	⊃ Window variables;
03800	X_WIDTH←40;  ⊃ INITIAL WINDOW WIDTH;
03900	Y_WIDTH←30;  ⊃ INITIAL WINDOW HEIGHT;
04000	DELTA_X←X_WIDTH/2.-6;
04100	DELTA_Y←Y_WIDTH/2.-6;
04200	
04300	
04400	⊃ Array limits;
04500	EDGE_LIMIT←1200;
04600	LT_LIMIT←600;
04700	LINE_LIMIT← 15;
04800	VERT_LIMIT←15;
04900	BUF_LIMIT←1200;
05000	
05100	
05200	END;
05300	
05400	REQUIRE INIT INITIALIZATION;
     

00100	
00200	
00300	
00400	BOOLEAN WANT_ALL; ⊃ If true then find all corners. Otherwise stop
00500			after finding first matching corner;
00600	BOOLEAN DISP_HIST; ⊃ IF TRUE THEN DISPLAY HISTOGRAMS;
00700	BOOLEAN DISP_POINTS; ⊃ IF TRUE THEN DISPLAY THETA-C POINTS;
00800	BOOLEAN DISP_VERT; ⊃ If true then make extra vertex displays;
00900	SHORT INTEGER EDGE_COUNT,EDGE_INDEX,LEDGE_INDEX;
01000	DEFINE EDGE_BLSIZE = "4", EBS = "4",EDGE_X="0", EDGE_Y="1",
01100		EDGE_TH="2", EDGE_C="3";
01200	DEFINE PI1 = "3.1415927", SQ2 = "1.414214";
01300	DEFINE PIT2 = "6.283185", PIO2 = "1.570796", PI6=".523595";
01400	DEFINE  BUF2_LIMIT="2", HUMP_LIMIT = "50";
01500	
01600	
01700	SHORT INTEGER X1,Y1,X2,Y2; ⊃ Window variables;
01800	
     

00100	
00200	
00300	PROCEDURE COR(INTEGER MODLINES,DIREC,SEARCH;
00400		REAL TOLER; REAL ARRAY CORNMOD);
00500	BEGIN "COR"
00600	
00700	SHORT INTEGER WSEARCH;
00800	
00900	SHORT REAL ARRAY EDGES[1:EDGE_LIMIT], 
01000		HUMPS[0:LINE_LIMIT,1:HUMP_LIMIT], VERTEX[1:VERT_LIMIT,1:10];
01100	SHORT REAL ARRAY INTER[1:2,1:5],LIN[1:3,1:5],FOLLOW[1:6];
01200	
01300	
01400	REQUIRE "DPY2.HDR[VIS,WAP]" SOURCE_FILE;
01500	REQUIRE "EDGED.HDR[VIS,WAP]" SOURCE_FILE;
01600	REQUIRE "LINE.FND[SYS,HE]" SOURCE_FILE;
01700	
01800	
01900	
02000	
02100	
02200	
02300	
02400	⊃  Conversion  from  Quam  format  picture  header  array to hand-eye
02500		library style parameters;
02600	
02700	SIMPLE PROCEDURE Q2HE(SAFE INTEGER ARRAY PIC);
02800		BEGIN
02900		INTEGER J;
03000	⊃		FOR J←0 STEP 1 UNTIL 9 DO
03100			OUTSTR("  PIC["&CVS(J)&"]="&CVS(PIC[J])ACRLF);
03200		IWID←PIC[SIZEX];
03300		FLINE←PIC[POSY];
03400		LSIDE←PIC[POSX];
03500		RSIDE←LSIDE+IWID-1;
03600		LLINE←FLINE+PIC[SIZEY]-1;
03700		LINLEN←PIC[SIZEL];
03800		BITS←PIC[BIT];
03900		END "Q2HE";
04000	
04100	⊃  Conversion from hand-eye library parameters to Quam format picture
04200		header array;
04300	
04400	SIMPLE PROCEDURE HE2Q(SAFE INTEGER ARRAY PIC);
04500		BEGIN
04600		PIC[SCALEX]←PIC[SCALEY]←1;
04700		PIC[POSX]←LSIDE;
04800		PIC[POSY]←FLINE;
04900		PIC[SIZEX]←RSIDE-LSIDE+1;
05000		PIC[SIZEY]←LLINE-FLINE+1;
05100		PIC[SIZEL]←HAT(PIC[SIZEX],36 DIV BITS);
05200		PIC[BIT]←BITS;
05300	END "HE2Q";
     

00100	⊃	BEGINNING OF TVSIX PACKAGE;
00200	
00300	SIMPLE PROCEDURE MINMAX(SAFE INTEGER ARRAY PARS);
00400		BEGIN INTEGER NI,NJ;
00500		NI←LINLEN*3;
00600		NJ←PARS[SIZEY];
00700	
00800		START_CODE
00900		LABEL LI,LJ;
01000		DEFINE A={1},I={2},J={3},P1={4},P2={5},P3={6};
01100		DEFINE FOO(X)={
01200			ILDB A,X;
01300			CAMGE A,XXMIN;
01400			MOVEM A,XXMIN;
01500			CAMLE A,XXMAX;
01600			MOVEM A,XXMAX;};
01700	
01800		MOVE P1,SUMPT1;
01900		MOVE P2,SUMPT2;
02000		MOVE P3,SUMPT3;
02100		MOVE J,NJ;
02200	LJ:	MOVE I,NI;
02300	LI:	FOO(P1)
02400		FOO(P2)
02500		FOO(P3)
02600		SOJG I,LI;
02700		SOJG J,LJ;
02800		END;
02900	
03000		END "MINMAX";
03100	
03200	⊃ Determines the size array needed for picture PIC,
03300		allocates an array,
03400		and sets and returns the appropriate PTR parameter;
03500	
03600	INTEGER SIMPROC PICMAK(PICTURE PIC);
03700		BEGIN
03800		DEFINE BHEAD(BUF)={ ((BUF+1) LAND '777777)};
03900		IF PIC[SIZEX]=0 THEN RETURN(0);
04000		PIC[SIZEL]←HAT(PIC[SIZEX],36 DIV PIC[BIT]);
04100		PICSIZE ← GETCOR(PIC[SIZEL]*PIC[SIZEY]);
04200		RETURN(PIC[PTR]←XPOINT(PIC[BIT],BHEAD(PICSIZE),-1));
04300		END "PICMAK";
     

00100	⊃	TVSIX REDUCTION ROUTINE;
00200	
00300	SIMPLE PROCEDURE REDUCER(SAFE INTEGER ARRAY PARS);
00400		BEGIN
00500		DEFINE Q={'10000};
00600		INTEGER NI,NJ,RPT,LL,SCALE;
00700		SCALE←(64*Q-1)%(XXMAX-XXMIN);
00800		NI←3*LINLEN;
00900		NJ←PARS[SIZEY];
01000		RPT←PARS[PTR];
01100		LL←PARS[SIZEL];
01200	
01300		START_CODE
01400		LABEL L,LI;
01500		DEFINE A={1},I={2},J={3},P1={4},P2={5},P3={6},R={7};
01600		DEFINE FOO(X)={
01700			ILDB A,X;
01800			SUB A,XXMIN;
01900			IMUL A,SCALE;
02000			ASH A,'777764;
02100			IDPB A,R;};
02200	
02300		MOVE P1,SUMPT1;
02400		MOVE P2,SUMPT2;
02500		MOVE P3,SUMPT3;
02600		MOVE R,RPT;
02700		MOVE J,NJ;
02800	LI:	MOVE I,NI;
02900	L:	FOO(P1)
03000		FOO(P2)
03100		FOO(P3)
03200		SOJG I,L;
03300		MOVE R,LL;
03400		ADDB R,RPT;
03500		SOJG J,LI;
03600		END;
03700	
03800		END "REDUCER";
     

00100	⊃ Super fast averager.  SUMS and CLPINC determine the number of 
00200		averages and clip level ranges;
00300	
00400	PROCEDURE SUMMER(INTEGER ARRAY PARS,SUM;INTEGER SUMS,CLPINC);
00500		BEGIN
00600		EXTERNAL PROCEDURE TVIN;
00700		EXTERNAL INTEGER PROCEDURE GLABEL(REFERENCE INTEGER FOO);
00800		DEFINE APOINT(S,L,P)={((35-(P)) LSH 30)+((S) LSH 24)+(L)};
00900		LINLEN←(PARS[SIZEX]-1)%9+1;
01000		TVSIZE←LINLEN*LINES;
01100			BEGIN INTEGER ARRAY TVBUF[1:TVSIZE];
01200			INTEGER SUMCNT;
01300			SUMPT1←APOINT(12,GLABEL(SUM[1,1,1]),-1);
01400			SUMPT2←SUMPT1+TVSIZE;
01500			SUMPT3←SUMPT2+TVSIZE;
01600			XXMIN←1 LSH 34;
01700			XXMAX←0;
01800			TVWORD←GIOWD(TVBUF);
01900			FOR SUMCNT←1 STEP 1 UNTIL SUMS DO
02000				BEGIN
02100				TCLIP←0;
02200				BCLIP←CLPINC-1;
02300				WHILE BCLIP ≤ 7 DO
02400					BEGIN
02500					TVIN;
02600					SUMSUB(TVBUF,SUMPT1,SUMPT2,SUMPT3);
02700					TCLIP←TCLIP+CLPINC;
02800					BCLIP←BCLIP+CLPINC;
02900					END;
03000				END;
03100			END;
03200		END "SUMMER";
03300	
03400	PROCEDURE TVSIX(SAFE INTEGER ARRAY PARS;INTEGER SUMS,CLPINC);
03500		BEGIN INTEGER ADR, TVSAV;
03600		PARS[SIZEL]←(PARS[SIZEX]-1)%6+1;
03700		TVSAV ← TVWORD;
03800		ADR←(TVWORD+1) LAND '777777;
03900		PARS[PTR]←XPOINT(6,ADR,-1);
04000		PARS[BIT]←6;
04100		Q2HE(PARS);
04200		LINLEN←(PARS[SIZEX]-1)%9+1;
04300		LINES←LLINE-FLINE+1;
04400			BEGIN INTEGER ARRAY SUM[1:3,1:LINES,1:LINLEN];
04500			SUMMER(PARS,SUM,SUMS,CLPINC);
04600	⊃ OUTSTR(" AFTER SUMMER, IN TVSIX "ACRLF);
04700			MINMAX(PARS);
04800	⊃  OUTSTR(" AFTER MINMAX, IN TVSIX "ACRLF);
04900			REDUCER(PARS);
05000	⊃  OUTSTR(" AFTER REDUCER, IN TVSIX "ACRLF);
05100			END;
05200		TVWORD ← TVSAV;
05300		END "TVSIX";
     

00100	
00200	SIMPLE PROCEDURE GETPICTURE;
00300	BEGIN
00400		SHORT INTEGER SUMS,CLPINC;
00500	  		IF DEB_EYE∨WSEARCH≥1 THEN
00600			OUTSTR(" WINDOW CENTER AT "&CVS(LOOK_AT[2])
00700				&"  "&CVS(LOOK_AT[3])ACRLF);
00800			SUMS←1;  CLPINC←1;
00900	
01000		TVCAM←LOOK_AT[1];
01100	         LSIDE←LOOK_AT[2]-(LOOK_AT[4] DIV 2);
01200	         RSIDE←LSIDE+LOOK_AT[4]-1;
01300	         FLINE←LOOK_AT[3]-(LOOK_AT[5] DIV 2);
01400	         LLINE←FLINE+LOOK_AT[5]-1;
01500		TCLIP←0; BCLIP←7;
01600	
01700	
01800			INTPNT;
01900			HE2Q(PIC);
02000			TVSIX(PIC,SUMS,CLPINC);
02100			Q2HE(PIC);
02200	END;
02300	
02400	
02500	
02600	
02700	PROCEDURE DISPLAY;
02800	 ⊃ Display the array of intensity numbers in the window;
02900	
03000	BEGIN "DISPLAY"
03100	SHORT INTEGER X,Y, SCALE, XBOUND,YBOUND;
03200	SHORT REAL NUMB,DEL, DELX,DELY, MINSCAL;
03300	SHORT INTEGER X1,Y1,X2,Y2;
03400	EXTERNAL INTEGER PROCEDURE GETPNT(INTEGER X,Y);
03500		X1←LOOK_AT[2]-(LOOK_AT[4] DIV 2);
03600		X2←LOOK_AT[2]+(LOOK_AT[4] DIV 2);
03700		Y1←LOOK_AT[3]-(LOOK_AT[5] DIV 2);
03800		Y2←LOOK_AT[3]+(LOOK_AT[5] DIV 2);
03900		INIT_DOMAIN(X1,Y2,X2,Y1); ⊃ Set scale for display;
04000		MINSCAL←SMALLER(LOOK_AT[4],LOOK_AT[5]);
04100		SCALE←(MINSCAL DIV 25)+1;
04200		XBOUND←TX(X1);
04300		YBOUND←TY(Y1);
04400		DELX←TX(X2)-XBOUND;
04500		DELY←TY(Y2)-YBOUND;
04600		NUMB←MINSCAL;
04700	⊃  OUTSTR(" IN DISPLAY-- NUMBER="&CVG(NUMB)ACRLF);
04800	⊃  OUTSTR(" XBOUND="&CVS(XBOUND)&"   YBOUND="&CVS(YBOUND)ACRLF);
04900		DEL←ABS(SMALLER(DELX,DELY))/(NUMB+1);
05000		XBOUND←XBOUND+15;
05100		YBOUND←YBOUND-25;
05200	
05300	    DPYTYP(-200,12,1); DPYSET(DPYBUF);
05400	    DPYBRT(5); DPYBIG(2);
05500		BOUNDARY(X1,Y2,X2,Y1);
05600		IF DEB_EYE THEN 
05700		BEGIN
05800		   AIVECT(-500,0); RVECT(0,320);
05900		   FOR X←0 STEP 1 UNTIL 16 DO 
06000		   BEGIN RVECT(-10,0); RIVECT(10,-20); END;
06100		   FOR X←0 STEP 1 UNTIL 3 DO 
06200		   BEGIN AIVECT(-530,100*X); DPYSST(CVS(5*X)); END;
06300	    AIVECT(-600,380); DPYSST("CLIPS");
06400	    AIVECT(-500,0); RVECT(IHIST[0]/(SCAL),0);
06500	    FOR X←0 STEP 1 UNTIL 14 DO 
06600		BEGIN RVECT(0,20); RVECT((IHIST[X+1]-IHIST[X])/(SCAL),0); END;
06700	    RVECT(0,20); RVECT(-IHIST[15]/(SCAL),0);
06800	    AIVECT(-600,40*(7-LOOK_AT[7])); RVECT(60,0);
06900	    AIVECT(-600,40*(8-LOOK_AT[6])); RVECT(60,0);
07000	    END;
07100	
07200	
07300	
07400	    AIVECT(-200,420); DPYSST("SCALE=1:"&CVS(SCALE)); DPYBIG(2);
07500	    FOR X←0 STEP SCALE UNTIL LOOK_AT[4]-1 DO
07600	    FOR Y←0 STEP SCALE UNTIL LOOK_AT[5]-1 DO 
07700		BEGIN
07800		   AIVECT(XBOUND+DEL*X,YBOUND-DEL*Y);
07900			DPYSST(CVS(GETPNT(X,Y))); 
08000		END;
08100		   DPYOUT(1); SETFORMAT(0,7);
08200	  END"DISPLAY";
08300	
08400	
08500	
08600	
08700	REQUIRE "IMAGE.SAI[SYS,HE]" SOURCE_FILE;
08800	
08900		WSEARCH←SEARCH;
09000	
09100		SRCHIMAG(MODLINES,DIREC,SEARCH,TOLER,CORNMOD);
09200	
09300	
09400	END "COR";
09500	
     

00100	
00200	
00300	
00400	
00500	SIMPLE MESSAGE PROCEDURE SRCH_IMAGE(INTEGER MODLINES,DIREC,SEARCH;
00600			     REAL TOLER; REAL ARRAY CORNMOD);
00700	  BEGIN         ⊃ globals LOOK_AT and DIR_EYE are used as I/O;
00800	
00900	SIMPLE INTEGER PROCEDURE LARGER(SHORT INTEGER L1,L2);
01000	IF L1>L2 THEN RETURN(L1) ELSE RETURN(L2);
01100	
01200		  EXFLAG←0;
01300	
01400			X_WIDTH←LOOK_AT[4];
01500			Y_WIDTH←LOOK_AT[5];
01600			DELTA_X←X_WIDTH/2.-6;
01700			DELTA_Y←Y_WIDTH/2.-6;
01800			IF SEARCH≥1 THEN
01900			BEGIN
02000				DELTA_X←DELTA_X+4;
02100				DELTA_Y←DELTA_Y+4;
02200			END;
02300			SIZE←X_WIDTH*Y_WIDTH;
02400			EDGE_LIMIT←LARGER(1200,SIZE);
02500			BUF_LIMIT←EDGE_LIMIT;
02600			LT_LIMIT←LARGER(600,SIZE DIV 4);
02700			LINE_LIMIT←LARGER(15,SIZE DIV 80);
02800			VERT_LIMIT←LINE_LIMIT;
02900			NLINES←NVERTEX←NCORNERS←0;
03000			IF DIR_EYE[0,1]<0 THEN WANT_ALL←-1 ELSE WANT_ALL←0;
03100			CAL_COMP←EYEFLG;
03200			CAL2_COMP←0;
03300	
03400	    COR(MODLINES,DIREC,SEARCH,TOLER,CORNMOD);
03500	    EYEFLG←EXFLAG;
03600	  END "SRCH_IMAGE";
03700	
03800	
03900	    ⊃ Main Program;
04000	
04100	    TVWORD←GIOWD(TVBUF); 
04200		BITS←6;
04300	 	  PUT_DATA(0,0,"EYE");        ⊃ DECLARE YOUR NAME ;
04400		  OUTSTR("EYE-ACTIVATED"ACRLF);
04500		  YES_EYE←TRUE ;
04600	 	  WHILE TRUE DO 
04700		BEGIN
04800		    MESS ← GET_ENTRY ('120,NULL,"EYE",NULL);
04900		    MESS ← QUEUE ('600,MESS); ⊃ ACTIVATE AND ACKNOWLEDGE ;
05000	 	  END;
05100	END "WALEYE";